package bootstrap

import (
	"gitee.com/guolianyu/kit/skit/bootstrap/monitor"
	confpb "gitee.com/guolianyu/kit/skit/third_party/config"
	"github.com/go-kratos/kratos/v2"
	"github.com/go-kratos/kratos/v2/log"
	"github.com/go-kratos/kratos/v2/transport"
	"github.com/google/wire"
)

var (
	ProviderSet = wire.NewSet(wire.Struct(new(AppConfig), "*"), NewLoggerProvider, NewApp)
)

type AppConfig struct {
	OpenSergo   *confpb.OpenSergo
	Registry    *confpb.Registry
	Tracer      *confpb.Trace
	Sentry      *confpb.Sentry
	Logger      log.Logger
	Language    *confpb.Language
	PprofServer *confpb.PprofServer
	Prometheus  *confpb.Prometheus
}

type App struct {
	config  *AppConfig
	srvInfo *ServiceInfo
	app     *kratos.App
	servers []transport.Server
}

func NewApp(serviceInfo *ServiceInfo, cfg *AppConfig, servers ...transport.Server) *App {
	a := &App{
		config:  cfg,
		srvInfo: serviceInfo,
		app:     nil,
		servers: servers,
	}
	//开启prometheus
	if proS := monitor.NewPrometheusServer(cfg.Prometheus); proS != nil {
		servers = append(servers, proS)
	}

	//开启调试服务pprof
	if pprofs := monitor.NewPProfServer(cfg.PprofServer); pprofs != nil {
		servers = append(servers, pprofs)
	}

	a.app = kratos.New(
		kratos.ID(serviceInfo.Id),
		kratos.Name(serviceInfo.Name),
		kratos.Version(serviceInfo.Version),
		kratos.Metadata(serviceInfo.Metadata),
		kratos.Logger(cfg.Logger),
		kratos.Server(
			servers...,
		),
		//注册服务实例
		kratos.Registrar(NewRegistrarProvider(cfg.Registry)),
	)
	return a
}

// Run 统一的运行应用生命周期，并且添加自定义需要开启的服务，如 监控、服务治理等
func (a *App) Run() error {
	//链路追踪
	if a.config.Tracer != nil {
		if err := NewTracerProvider(a.config.Tracer, a.srvInfo); err != nil {
			return err
		}
	}

	//服务治理
	if a.config.OpenSergo != nil {
		if err := NewOpenSergo(a.app, a.config.OpenSergo); err != nil {
			return err
		}
	}

	//日志
	if a.config.Sentry != nil {
		if err := NewSentry(a.config.Sentry); err != nil {
			return err
		}
	}

	return a.app.Run()
}
